{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting dataset/train-images-idx3-ubyte.gz\n",
      "Extracting dataset/train-labels-idx1-ubyte.gz\n",
      "Extracting dataset/t10k-images-idx3-ubyte.gz\n",
      "Extracting dataset/t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "#加载数据集\n",
    "mnist=input_data.read_data_sets('dataset/',one_hot=True);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type of 'mnist is <class 'tensorflow.contrib.learn.python.learn.datasets.base.Datasets'>'\n",
      "number of train data is 55000\n",
      "number of test data is 10000\n"
     ]
    }
   ],
   "source": [
    "#mnist数据集类型，训练集和测试集数量\n",
    "print(\"type of 'mnist is %s'\" % (type(mnist)))\n",
    "print(\"number of train data is %d\" % mnist.train.num_examples)\n",
    "print(\"number of test data is %d\" % mnist.test.num_examples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type train_img is <class 'numpy.ndarray'>\n",
      "type train_label is <class 'numpy.ndarray'>\n",
      "Type of test_img is <class 'numpy.ndarray'>\n",
      "Type of test_label is <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "#训练集和测试集的图片和标签类型\n",
    "train_img=mnist.train.images\n",
    "print('type train_img is %s' % (type(train_img)))\n",
    "\n",
    "train_label=mnist.train.labels\n",
    "print('type train_label is %s' % (type(train_label)))\n",
    "\n",
    "test_img=mnist.test.images\n",
    "print(\"Type of test_img is %s\" % (type(test_img)))\n",
    "\n",
    "test_label=mnist.test.labels\n",
    "print(\"Type of test_label is %s\" % (type(test_label)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQEAAAECCAYAAAD+eGJTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAOoUlEQVR4nO3df4hXdb7H8de7TTPSZEqTqXWv3Qhj28iZhohJFi/bla4MZEVyrT8MLk3lCmstdsOgX3BjuKzdKwmClq1bu16i7Ae25IosZf0hO4bUmJWbzFAy6pZSYxQX9b1/zHF3tmY+Z+b765yZ9/MBMt85r5n5vj3ly3PO9+P5mrsLQFxnFT0AgGJRAkBwlAAQHCUABEcJAMFRAkBwhZSAmd1oZh+Z2Z/N7MEiZkgxs14ze9/M9ppZdwnm2WRmR82sZ8i2C8xsh5kdyD42lWy+R83sULYP95rZogLnm21mfzSzD8xsn5n9Ittein2YmK8h+9AavU7AzH4g6WNJ/yrpM0l/krTU3T9o6CAJZtYrqc3dPy96Fkkys59KOiHpN+7+k2zbf0s65u5dWZE2uft/lmi+RyWdcPdfFTHTUGbWLKnZ3d81s2mS9khaLOlOlWAfJuZbogbswyKOBK6V9Gd3P+ju/y/p/yTdVMAc44a7vyXp2Hc23yRpc/Z4swb/pynECPOVhrv3u/u72eMBSfslXaKS7MPEfA1RRAlcIunTIZ9/pgb+hkfJJf3BzPaYWWfRw4xglrv3Z48PS5pV5DAjWGFm72WnC4WdrgxlZnMktUjarRLuw+/MJzVgH3JhcHjz3b1V0r9J+nl2uFtaPnhOV7b13+slXSZpnqR+SWsKnUaSmU2V9JKkle7+1dCsDPtwmPkasg+LKIFDkmYP+fyH2bbScPdD2cejkl7W4ClM2RzJziXPnFMeLXief+DuR9z9lLuflrRRBe9DM5ukwT9gv3X3rdnm0uzD4eZr1D4sogT+JOlyM7vUzCZL+ndJrxUwx7DM7Lzs4ozM7DxJCyX1pL+rEK9JWpY9Xibp1QJn+Z4zf7gyN6vAfWhmJukZSfvd/ckhUSn24UjzNWofNvzVAUnKXur4X0k/kLTJ3f+r4UOMwMz+WYN/+0vS2ZJ+V/R8ZrZF0gJJMyQdkfSIpFckvSDpR5L6JC1x90Iuzo0w3wINHsa6pF5Jdw85/270fPMl7ZL0vqTT2ebVGjzvLnwfJuZbqgbsw0JKAEB5cGEQCI4SAIKjBIDgKAEgOEoACK7QEijxklxJzFetMs9X5tmkxs5X9JFAqf9DiPmqVeb5yjyb1MD5ii4BAAWrarGQmd0oaa0GV/497e5dOV/PyiSgIO5uw22vuAQquTkIJQAUZ6QSqOZ0gJuDABNANSUwHm4OAiDH2fV+guyljrJfiQXCqqYERnVzEHffIGmDxDUBoIyqOR0o9c1BAIxOxUcC7n7SzFZI2q6/3xxkX80mA9AQDb2pCKcDQHHq8RIhgAmAEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4CgBIDhKAAiOEgCCO7voARDHwoULk/kdd9yRzDs6OpJ5U1NTMn/xxReT+QMPPJDMe3t7k/l4VVUJmFmvpAFJpySddPe2WgwFoHFqcSTwL+7+eQ1+DoACcE0ACK7aEnBJfzCzPWbWWYuBADRWtacD8939kJldJGmHmX3o7m8N/YKsHCgIoKSqOhJw90PZx6OSXpZ07TBfs8Hd27hoCJRTxSVgZueZ2bQzjyUtlNRTq8EANEY1pwOzJL1sZmd+zu/c/Y2aTIVCnHvuucl88eLFyXzVqlXJfO7cucn89OnTybyrqyuZHzx4MJmvW7cumd96663JfM2aNcl8vKq4BNz9oKSrazgLgALwEiEQHCUABEcJAMFRAkBwlAAQHCUABMf9BAKZM2dOMl+xYkUyv++++6p6/q1btybz559/Pplv27Ytmc+cOTOZP/fcc8m8ubk5mU9UHAkAwVECQHCUABAcJQAERwkAwVECQHCUABCcuXvjnsyscU+G7+nu7k7mLS0tyfz48ePJfOnSpcl8x44dyTzP9OnTk/natWuT+eHDh5P5+vXrk3lfX18yLzt3t+G2cyQABEcJAMFRAkBwlAAQHCUABEcJAMFRAkBwrBMYR6644opkvnHjxmR+/fXXJ/Pdu3cn80WLFiXzvHUEeaZNm5bMW1tbk/mbb75Z1fNPdKwTADAsSgAIjhIAgqMEgOAoASA4SgAIjhIAguN9B0rkyiuvTOb3339/Mm9vb0/meesAOjo6knm16wDyPPHEE8n8nnvuSeadnZ3J/Nlnnx3zTBHkHgmY2SYzO2pmPUO2XWBmO8zsQPaxqb5jAqiX0ZwO/FrSjd/Z9qCkne5+uaSd2ecAxqHcEnD3tyQd+87mmyRtzh5vlrS4tmMBaJRKLwzOcvf+7PFhSbNqNA+ABqv6wqC7e+ofBplZp6T0FRsAhan0SOCImTVLUvbx6Ehf6O4b3L3N3dsqfC4AdVRpCbwmaVn2eJmkV2szDoBGyz0dMLMtkhZImmFmn0l6RFKXpBfM7D8k9UlaUs8hJ4pzzjknmS9fvjyZ33nnnck873X8et8PoFp59ws466z031mTJ0+u5Thh5JaAu4/0jhI/q/EsAArAsmEgOEoACI4SAIKjBIDgKAEgOEoACI73HWigrq6uZL5q1apkvm/fvmR+++23J/Oenp5kXm8XX3xxMs/7/Z06dSqZz507N5l/8cUXyXyi430HAAyLEgCCowSA4CgBIDhKAAiOEgCCowSA4HjfgRq67bbbqspPnDiRzJ966qlkXvZ1ALt27Urm06dPT+ZffvllMud+ApXhSAAIjhIAgqMEgOAoASA4SgAIjhIAgqMEgOBYJzAGkyZNSuYrV65M5pdeemky37RpUzLfuHFjMq+3q6++Oplv2bIlmef9/vPubfH2228n8/7+/mSO4XEkAARHCQDBUQJAcJQAEBwlAARHCQDBUQJAcKwTGIOHH344mV933XXJvLe3N5k/9thjYx2pph566KFkvnr16mSe974Be/bsSeatra3JfN26dckclck9EjCzTWZ21Mx6hmx71MwOmdne7Nei+o4JoF5Gczrwa0k3DrP9f9x9Xvbr97UdC0Cj5JaAu78l6VgDZgFQgGouDK4ws/ey04Wmmk0EoKEqLYH1ki6TNE9Sv6Q1I32hmXWaWbeZdVf4XADqqKIScPcj7n7K3U9L2ijp2sTXbnD3Nndvq3RIAPVTUQmYWfOQT2+WVOy9rgFULHedgJltkbRA0gwz+0zSI5IWmNk8SS6pV9Ld9RuxPK655pqqvn/79u3J/NNPP03mHR0dyTxvvvb29mR+1VVXJfPHH388mT/99NPJPO/3j2LkloC7Lx1m8zN1mAVAAVg2DARHCQDBUQJAcJQAEBwlAARHCQDBWd693mv6ZGaNe7I6mDdvXjJ//fXXk3lzc3Myr7eenvSarnfeeSeZ33vvvVU9/yeffJLM896X4JZbbknmr7zyylhHCsXdbbjtHAkAwVECQHCUABAcJQAERwkAwVECQHCUABAc7zswBgcOHEjmfX19yTxvncDXX3+dzPNeB9+6dWsyf+ONN5L5N998k8zz3HDDDck8bx1A3jqCnTt3jnkm5ONIAAiOEgCCowSA4CgBIDhKAAiOEgCCowSA4LifQA01NaXfknH27NnJ/Ntvv03mH3/88ZhnqqULL7wwmee9zn/++ecn848++iiZt7a2JvNq1zlMdNxPAMCwKAEgOEoACI4SAIKjBIDgKAEgOEoACI77CdTQ8ePHq8rL7uTJk8l8YGAgmeetE+jv70/mU6ZMSeasE6hM7pGAmc02sz+a2Qdmts/MfpFtv8DMdpjZgexjeqUMgFIazenASUm/dPcfS7pO0s/N7MeSHpS0090vl7Qz+xzAOJNbAu7e7+7vZo8HJO2XdImkmyRtzr5ss6TFdZoRQB2N6cKgmc2R1CJpt6RZ7n7mJO6wpFm1HQ1AI4z6wqCZTZX0kqSV7v6V2d//LYK7+0j/OMjMOiV1VjsogPoY1ZGAmU3SYAH81t3P3NL2iJk1Z3mzpKPDfa+7b3D3Nndvq8XAAGprNK8OmKRnJO139yeHRK9JWpY9Xibp1dqPB6Decu8nYGbzJe2S9L6k09nm1Rq8LvCCpB9J6pO0xN2P5fysCX0/gYku734Jefc7mDFjRjJvaWlJ5nv37k3mSBvpfgK51wTc/W1Jw36zpJ9VMxSA4rFsGAiOEgCCowSA4CgBIDhKAAiOEgCC434CGLWZM2cm86lTpybzvDUp4/1+C+MVRwJAcJQAEBwlAARHCQDBUQJAcJQAEBwlAATHOgH8zUUXXZTMly9fnswnT56czD/88MNkfuxY8nYUqBOOBIDgKAEgOEoACI4SAIKjBIDgKAEgOEoACI51AvibKVOmJPP29vaqfv5dd92VzAcGBqr6+agMRwJAcJQAEBwlAARHCQDBUQJAcJQAEBwlAARnefeCN7PZkn4jaZYkl7TB3dea2aOS7pL0l+xLV7v773N+VvrJANSNu9tw20dTAs2Smt39XTObJmmPpMWSlkg64e6/Gu0QlABQnJFKIHfFoLv3S+rPHg+Y2X5Jl9R2PABFGdM1ATObI6lF0u5s0woze8/MNplZU62HA1B/oy4BM5sq6SVJK939K0nrJV0maZ4GjxTWjPB9nWbWbWbd1Y8LoNZyrwlIkplNkrRN0nZ3f3KYfI6kbe7+k5yfwzUBoCAjXRPIPRIwM5P0jKT9Qwsgu2B4xs2SeqodEkDjjebVgfmSdkl6X9LpbPNqSUs1eCrgknol3Z1dREz9LI4EgIJU/BJhLVECQHEqPh0AMLFRAkBwlAAQHCUABEcJAMFRAkBwlAAQHCUABEcJAMFRAkBwlAAQHCUABEcJAMFRAkBwlAAQXO7dhmvsc0l9Qz6fkW0rK+arTpnnK/NsUu3n+6eRgobeVOR7T27W7e5thQ2Qg/mqU+b5yjyb1Nj5OB0AgqMEgOCKLoENBT9/HuarTpnnK/NsUgPnK/SaAIDiFX0kAKBglAAQHCUABEcJAMFRAkBwfwXB40QV5QInPAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#可视化\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "rand=np.random.randint(train_img.shape[0],size=1)\n",
    "\n",
    "for i in rand:\n",
    "    show_img=np.reshape(train_img[i,:],(28,28))\n",
    "    show_label=np.argmax(train_label[i,:])\n",
    "    plt.matshow(show_img,cmap=plt.get_cmap('gray'))\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "#保存为RGB图片\n",
    "from PIL import Image\n",
    "import struct\n",
    "import gzip\n",
    "\n",
    "def save_imgRgb(path_img):\n",
    "    with gzip.open(path_img) as bytestream:\n",
    "        index=0\n",
    "        buf=bytestream.read()\n",
    "        magic,images,row,col=struct.unpack_from('>IIII',buf,index)\n",
    "        index+=struct.calcsize('>IIII')\n",
    "        for i in range(10):\n",
    "            img=Image.new('RGB',(col,row))\n",
    "            for x in range(row):\n",
    "                for y in range(col):\n",
    "                    img.putpixel((y,x),int(struct.unpack_from('>B',buf,index)[0]))\n",
    "                    index+=struct.calcsize('>B')\n",
    "            img.save('img_rgb/'+str(i)+'.png')\n",
    "    return\n",
    "\n",
    "save_imgRgb('dataset/train-images-idx3-ubyte.gz')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "#保存为GRAY图片\n",
    "from PIL import Image\n",
    "\n",
    "def save_imgGray(path_img):\n",
    "    for i in range(10):\n",
    "        img=mnist.train.images[i,:]\n",
    "        img=img.reshape(28,28)\n",
    "        name_img='img_gray/'+'%d.jpg' % i\n",
    "        Image.fromarray((img*255).astype('uint8'),mode='L').save(name_img)\n",
    "    return \n",
    "\n",
    "save_imgGray('dataset/train-images-idx3-ubyte.gz')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "#使用逻辑回归训练数据集\n",
    "\n",
    "X=tf.placeholder(tf.float32,[None,784])#输入向量X\n",
    "y=tf.placeholder(tf.float32,[None,10])#输出类别y\n",
    "\n",
    "#模型参数\n",
    "W=tf.Variable(tf.zeros([784,10]))#权重\n",
    "b=tf.Variable(tf.zeros([10]))#偏置\n",
    "\n",
    "#使用softmax()对输出数据进行处理\n",
    "actv=tf.nn.softmax(tf.matmul(X,W)+b)\n",
    "\n",
    "#使用交叉熵损失函数\n",
    "loss=tf.reduce_mean(-tf.reduce_sum(y*tf.log(tf.clip_by_value(actv,1e-10,1.0)),reduction_indices=1))\n",
    "\n",
    "#使用梯度下降优化参数\n",
    "lr=0.01\n",
    "optm=tf.train.AdamOptimizer(lr).minimize(loss)\n",
    "\n",
    "#判断预测值和标签值是否已有一样\n",
    "pred=tf.equal(tf.argmax(actv,1),tf.argmax(y,1))\n",
    "\n",
    "#求pred的均值，即为准确率\n",
    "accr=tf.reduce_mean(tf.cast(pred,tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch:0000/10001,loss:0.342632,train_acc:0.916545,test_acc:0.920500\n",
      "Epoch:0500/10001,loss:0.230439,train_acc:0.931709,test_acc:0.908200\n",
      "Epoch:1000/10001,loss:0.232333,train_acc:0.937145,test_acc:0.909700\n",
      "Epoch:1500/10001,loss:0.230566,train_acc:0.934455,test_acc:0.907100\n",
      "Epoch:2000/10001,loss:0.234246,train_acc:0.938109,test_acc:0.914200\n",
      "Epoch:2500/10001,loss:0.231380,train_acc:0.939127,test_acc:0.912500\n",
      "Epoch:3000/10001,loss:0.232131,train_acc:0.940018,test_acc:0.913700\n",
      "Epoch:3500/10001,loss:0.231499,train_acc:0.932655,test_acc:0.906700\n",
      "Epoch:4000/10001,loss:0.231304,train_acc:0.937836,test_acc:0.910900\n",
      "Epoch:4500/10001,loss:0.231856,train_acc:0.934018,test_acc:0.907800\n",
      "Epoch:5000/10001,loss:0.230909,train_acc:0.936236,test_acc:0.912900\n",
      "Epoch:5500/10001,loss:0.232853,train_acc:0.930345,test_acc:0.905400\n",
      "Epoch:6000/10001,loss:0.232381,train_acc:0.925836,test_acc:0.901300\n",
      "Epoch:6500/10001,loss:0.231979,train_acc:0.926564,test_acc:0.902900\n",
      "Epoch:7000/10001,loss:0.232359,train_acc:0.935945,test_acc:0.910200\n",
      "Epoch:7500/10001,loss:0.232027,train_acc:0.936582,test_acc:0.912000\n",
      "Epoch:8000/10001,loss:0.231637,train_acc:0.937400,test_acc:0.913000\n",
      "Epoch:8500/10001,loss:0.231750,train_acc:0.926673,test_acc:0.899100\n",
      "Epoch:9000/10001,loss:0.230663,train_acc:0.933600,test_acc:0.909700\n",
      "Epoch:9500/10001,loss:0.230132,train_acc:0.936509,test_acc:0.912400\n",
      "Epoch:10000/10001,loss:0.230191,train_acc:0.937764,test_acc:0.911600\n",
      "Finsh!\n"
     ]
    }
   ],
   "source": [
    "#初始化\n",
    "init_op=tf.global_variables_initializer()\n",
    "\n",
    "#设置超参数\n",
    "epochs_num=10001\n",
    "batch_size=100\n",
    "display_step=500\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init_op)\n",
    "    for epoch in range(epochs_num):\n",
    "        avg_loss=0\n",
    "        #计算训练数据可以划分多少个batch大小的组\n",
    "        num_batch=int(mnist.train.num_examples/batch_size)\n",
    "                \n",
    "        for i in range(num_batch):\n",
    "            #next_batch():第一次取1-10，第二次取11-20,...\n",
    "            batch_xs,batch_ys=mnist.train.next_batch(batch_size)\n",
    "            #开始训练\n",
    "            feeds={X:batch_xs,y:batch_ys}\n",
    "            sess.run(optm,feed_dict=feeds)\n",
    "            #累积计算总损失值\n",
    "            avg_loss+=sess.run(loss,feed_dict=feeds)/num_batch\n",
    "        \n",
    "        #打印数据\n",
    "        if (epoch % display_step==0):\n",
    "            #全部训练集\n",
    "            feed_train={X:train_img,y:train_label}\n",
    "            #测试\n",
    "            feed_test={X:test_img,y:test_label}\n",
    "            train_acc=sess.run(accr,feed_dict=feed_train)\n",
    "            test_acc=sess.run(accr,feed_dict=feed_test)\n",
    "            \n",
    "            #打印参数\n",
    "            print('Epoch:%04d/%04d,loss:%.6f,train_acc:%.6f,test_acc:%.6f' % \n",
    "                 (epoch,epochs_num,avg_loss,train_acc,test_acc))\n",
    "\n",
    "print('Finsh!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
